1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package com.sun.media.sound;
26
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33
34 import javax.sound.midi.MidiChannel;
35 import javax.sound.midi.Patch;
36
37
38
39
40
41
42 public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
43
44 private static boolean[] dontResetControls = new boolean[128];
45 static {
46 for (int i = 0; i < dontResetControls.length; i++)
47 dontResetControls[i] = false;
48
49 dontResetControls[0] = true;
50 dontResetControls[32] = true;
51 dontResetControls[7] = true;
52 dontResetControls[8] = true;
53 dontResetControls[10] = true;
54 dontResetControls[11] = true;
55 dontResetControls[91] = true;
56 dontResetControls[92] = true;
57 dontResetControls[93] = true;
58 dontResetControls[94] = true;
59 dontResetControls[95] = true;
60 dontResetControls[70] = true;
61 dontResetControls[71] = true;
62 dontResetControls[72] = true;
63 dontResetControls[73] = true;
64 dontResetControls[74] = true;
65 dontResetControls[75] = true;
66 dontResetControls[76] = true;
67 dontResetControls[77] = true;
68 dontResetControls[78] = true;
69 dontResetControls[79] = true;
70 dontResetControls[120] = true;
71 dontResetControls[121] = true;
72 dontResetControls[122] = true;
73 dontResetControls[123] = true;
74 dontResetControls[124] = true;
75 dontResetControls[125] = true;
76 dontResetControls[126] = true;
77 dontResetControls[127] = true;
78
79 dontResetControls[6] = true;
80 dontResetControls[38] = true;
81 dontResetControls[96] = true;
82 dontResetControls[97] = true;
83 dontResetControls[98] = true;
84 dontResetControls[99] = true;
85 dontResetControls[100] = true;
86 dontResetControls[101] = true;
87
88 }
89
90 private static final int RPN_NULL_VALUE = (127 << 7) + 127;
91 private int rpn_control = RPN_NULL_VALUE;
92 private int nrpn_control = RPN_NULL_VALUE;
93 protected double portamento_time = 1;
94 protected int[] portamento_lastnote = new int[128];
95 protected int portamento_lastnote_ix = 0;
96 private boolean portamento = false;
97 private boolean mono = false;
98 private boolean mute = false;
99 private boolean solo = false;
100 private boolean solomute = false;
101 private Object control_mutex;
102 private int channel;
103 private SoftVoice[] voices;
104 private int bank;
105 private int program;
106 private SoftSynthesizer synthesizer;
107 private SoftMainMixer mainmixer;
108 private int[] polypressure = new int[128];
109 private int channelpressure = 0;
110 private int[] controller = new int[128];
111 private int pitchbend;
112 private double[] co_midi_pitch = new double[1];
113 private double[] co_midi_channel_pressure = new double[1];
114 protected SoftTuning tuning = new SoftTuning();
115 protected int tuning_bank = 0;
116 protected int tuning_program = 0;
117 protected SoftInstrument current_instrument = null;
118 protected ModelChannelMixer current_mixer = null;
119 protected ModelDirector current_director = null;
120
121
122 protected int cds_control_number = -1;
123 protected ModelConnectionBlock[] cds_control_connections = null;
124 protected ModelConnectionBlock[] cds_channelpressure_connections = null;
125 protected ModelConnectionBlock[] cds_polypressure_connections = null;
126 protected boolean sustain = false;
127 protected boolean[][] keybasedcontroller_active = null;
128 protected double[][] keybasedcontroller_value = null;
129
130 private class MidiControlObject implements SoftControl {
131 double[] pitch = co_midi_pitch;
132 double[] channel_pressure = co_midi_channel_pressure;
133 double[] poly_pressure = new double[1];
134
135 public double[] get(int instance, String name) {
136 if (name == null)
137 return null;
138 if (name.equals("pitch"))
139 return pitch;
140 if (name.equals("channel_pressure"))
141 return channel_pressure;
142 if (name.equals("poly_pressure"))
143 return poly_pressure;
144 return null;
145 }
146 }
147
148 private SoftControl[] co_midi = new SoftControl[128];
149 {
150 for (int i = 0; i < co_midi.length; i++) {
151 co_midi[i] = new MidiControlObject();
152 }
153 }
154
155 private double[][] co_midi_cc_cc = new double[128][1];
156 private SoftControl co_midi_cc = new SoftControl() {
157 double[][] cc = co_midi_cc_cc;
158 public double[] get(int instance, String name) {
159 if (name == null)
160 return null;
161 return cc[Integer.parseInt(name)];
162 }
163 };
164 Map<Integer, int[]> co_midi_rpn_rpn_i = new HashMap<Integer, int[]>();
165 Map<Integer, double[]> co_midi_rpn_rpn = new HashMap<Integer, double[]>();
166 private SoftControl co_midi_rpn = new SoftControl() {
167 Map<Integer, double[]> rpn = co_midi_rpn_rpn;
168 public double[] get(int instance, String name) {
169 if (name == null)
170 return null;
171 int iname = Integer.parseInt(name);
172 double[] v = rpn.get(iname);
173 if (v == null) {
174 v = new double[1];
175 rpn.put(iname, v);
176 }
177 return v;
178 }
179 };
180 Map<Integer, int[]> co_midi_nrpn_nrpn_i = new HashMap<Integer, int[]>();
181 Map<Integer, double[]> co_midi_nrpn_nrpn = new HashMap<Integer, double[]>();
182 private SoftControl co_midi_nrpn = new SoftControl() {
183 Map<Integer, double[]> nrpn = co_midi_nrpn_nrpn;
184 public double[] get(int instance, String name) {
185 if (name == null)
186 return null;
187 int iname = Integer.parseInt(name);
188 double[] v = nrpn.get(iname);
189 if (v == null) {
190 v = new double[1];
191 nrpn.put(iname, v);
192 }
193 return v;
194 }
195 };
196
197 private static int restrict7Bit(int value)
198 {
199 if(value < 0) return 0;
200 if(value > 127) return 127;
201 return value;
202 }
203
204 private static int restrict14Bit(int value)
205 {
206 if(value < 0) return 0;
207 if(value > 16256) return 16256;
208 return value;
209 }
210
211 public SoftChannel(SoftSynthesizer synth, int channel) {
212 this.channel = channel;
213 this.voices = synth.getVoices();
214 this.synthesizer = synth;
215 this.mainmixer = synth.getMainMixer();
216 control_mutex = synth.control_mutex;
217 resetAllControllers(true);
218 }
219
220 private int findFreeVoice(int x) {
221 if(x == -1)
222 {
223
224
225
226
227
228 return -1;
229 }
230 for (int i = x; i < voices.length; i++)
231 if (!voices[i].active)
232 return i;
233
234
235
236 int vmode = synthesizer.getVoiceAllocationMode();
237 if (vmode == 1) {
238
239
240
241
242 int steal_channel = channel;
243 for (int j = 0; j < voices.length; j++) {
244 if (voices[j].stealer_channel == null) {
245 if (steal_channel == 9) {
246 steal_channel = voices[j].channel;
247 } else {
248 if (voices[j].channel != 9) {
249 if (voices[j].channel > steal_channel)
250 steal_channel = voices[j].channel;
251 }
252 }
253 }
254 }
255
256 int voiceNo = -1;
257
258 SoftVoice v = null;
259
260 for (int j = 0; j < voices.length; j++) {
261 if (voices[j].channel == steal_channel) {
262 if (voices[j].stealer_channel == null && !voices[j].on) {
263 if (v == null) {
264 v = voices[j];
265 voiceNo = j;
266 }
267 if (voices[j].voiceID < v.voiceID) {
268 v = voices[j];
269 voiceNo = j;
270 }
271 }
272 }
273 }
274
275 if (voiceNo == -1) {
276 for (int j = 0; j < voices.length; j++) {
277 if (voices[j].channel == steal_channel) {
278 if (voices[j].stealer_channel == null) {
279 if (v == null) {
280 v = voices[j];
281 voiceNo = j;
282 }
283 if (voices[j].voiceID < v.voiceID) {
284 v = voices[j];
285 voiceNo = j;
286 }
287 }
288 }
289 }
290 }
291
292 return voiceNo;
293
294 } else {
295
296
297
298
299
300
301 int voiceNo = -1;
302
303 SoftVoice v = null;
304
305 for (int j = 0; j < voices.length; j++) {
306 if (voices[j].stealer_channel == null && !voices[j].on) {
307 if (v == null) {
308 v = voices[j];
309 voiceNo = j;
310 }
311 if (voices[j].voiceID < v.voiceID) {
312 v = voices[j];
313 voiceNo = j;
314 }
315 }
316 }
317
318 if (voiceNo == -1) {
319
320 for (int j = 0; j < voices.length; j++) {
321 if (voices[j].stealer_channel == null) {
322 if (v == null) {
323 v = voices[j];
324 voiceNo = j;
325 }
326 if (voices[j].voiceID < v.voiceID) {
327 v = voices[j];
328 voiceNo = j;
329 }
330 }
331 }
332 }
333
334 return voiceNo;
335 }
336
337 }
338
339 protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID,
340 int noteNumber, int velocity, int delay, ModelConnectionBlock[] connectionBlocks,
341 ModelChannelMixer channelmixer, boolean releaseTriggered) {
342 if (voice.active) {
343
344 voice.stealer_channel = this;
345 voice.stealer_performer = p;
346 voice.stealer_voiceID = voiceID;
347 voice.stealer_noteNumber = noteNumber;
348 voice.stealer_velocity = velocity;
349 voice.stealer_extendedConnectionBlocks = connectionBlocks;
350 voice.stealer_channelmixer = channelmixer;
351 voice.stealer_releaseTriggered = releaseTriggered;
352 for (int i = 0; i < voices.length; i++)
353 if (voices[i].active && voices[i].voiceID == voice.voiceID)
354 voices[i].soundOff();
355 return;
356 }
357
358 voice.extendedConnectionBlocks = connectionBlocks;
359 voice.channelmixer = channelmixer;
360 voice.releaseTriggered = releaseTriggered;
361 voice.voiceID = voiceID;
362 voice.tuning = tuning;
363 voice.exclusiveClass = p.exclusiveClass;
364 voice.softchannel = this;
365 voice.channel = channel;
366 voice.bank = bank;
367 voice.program = program;
368 voice.instrument = current_instrument;
369 voice.performer = p;
370 voice.objects.clear();
371 voice.objects.put("midi", co_midi[noteNumber]);
372 voice.objects.put("midi_cc", co_midi_cc);
373 voice.objects.put("midi_rpn", co_midi_rpn);
374 voice.objects.put("midi_nrpn", co_midi_nrpn);
375 voice.noteOn(noteNumber, velocity, delay);
376 voice.setMute(mute);
377 voice.setSoloMute(solomute);
378 if (releaseTriggered)
379 return;
380 if (controller[84] != 0) {
381 voice.co_noteon_keynumber[0]
382 = (tuning.getTuning(controller[84]) / 100.0)
383 * (1f / 128f);
384 voice.portamento = true;
385 controlChange(84, 0);
386 } else if (portamento) {
387 if (mono) {
388 if (portamento_lastnote[0] != -1) {
389 voice.co_noteon_keynumber[0]
390 = (tuning.getTuning(portamento_lastnote[0]) / 100.0)
391 * (1f / 128f);
392 voice.portamento = true;
393 controlChange(84, 0);
394 }
395 portamento_lastnote[0] = noteNumber;
396 } else {
397 if (portamento_lastnote_ix != 0) {
398 portamento_lastnote_ix--;
399 voice.co_noteon_keynumber[0]
400 = (tuning.getTuning(
401 portamento_lastnote[portamento_lastnote_ix])
402 / 100.0)
403 * (1f / 128f);
404 voice.portamento = true;
405 }
406 }
407 }
408 }
409
410 public void noteOn(int noteNumber, int velocity) {
411 noteOn(noteNumber, velocity, 0);
412 }
413
414
415
416
417 protected void noteOn(int noteNumber, int velocity, int delay) {
418 noteNumber = restrict7Bit(noteNumber);
419 velocity = restrict7Bit(velocity);
420 noteOn_internal(noteNumber, velocity, delay);
421 if (current_mixer != null)
422 current_mixer.noteOn(noteNumber, velocity);
423 }
424
425 private void noteOn_internal(int noteNumber, int velocity, int delay) {
426
427 if (velocity == 0) {
428 noteOff_internal(noteNumber, 64);
429 return;
430 }
431
432 synchronized (control_mutex) {
433 if (sustain) {
434 sustain = false;
435 for (int i = 0; i < voices.length; i++) {
436 if ((voices[i].sustain || voices[i].on)
437 && voices[i].channel == channel && voices[i].active
438 && voices[i].note == noteNumber) {
439 voices[i].sustain = false;
440 voices[i].on = true;
441 voices[i].noteOff(0);
442 }
443 }
444 sustain = true;
445 }
446
447 mainmixer.activity();
448
449 if (mono) {
450 if (portamento) {
451 boolean n_found = false;
452 for (int i = 0; i < voices.length; i++) {
453 if (voices[i].on && voices[i].channel == channel
454 && voices[i].active
455 && voices[i].releaseTriggered == false) {
456 voices[i].portamento = true;
457 voices[i].setNote(noteNumber);
458 n_found = true;
459 }
460 }
461 if (n_found) {
462 portamento_lastnote[0] = noteNumber;
463 return;
464 }
465 }
466
467 if (controller[84] != 0) {
468 boolean n_found = false;
469 for (int i = 0; i < voices.length; i++) {
470 if (voices[i].on && voices[i].channel == channel
471 && voices[i].active
472 && voices[i].note == controller[84]
473 && voices[i].releaseTriggered == false) {
474 voices[i].portamento = true;
475 voices[i].setNote(noteNumber);
476 n_found = true;
477 }
478 }
479 controlChange(84, 0);
480 if (n_found)
481 return;
482 }
483 }
484
485 if (mono)
486 allNotesOff();
487
488 if (current_instrument == null) {
489 current_instrument
490 = synthesizer.findInstrument(program, bank, channel);
491 if (current_instrument == null)
492 return;
493 if (current_mixer != null)
494 mainmixer.stopMixer(current_mixer);
495 current_mixer = current_instrument.getSourceInstrument()
496 .getChannelMixer(this, synthesizer.getFormat());
497 if (current_mixer != null)
498 mainmixer.registerMixer(current_mixer);
499 current_director = current_instrument.getDirector(this, this);
500 applyInstrumentCustomization();
501 }
502 prevVoiceID = synthesizer.voiceIDCounter++;
503 firstVoice = true;
504 voiceNo = 0;
505
506 int tunedKey = (int)(Math.round(tuning.getTuning(noteNumber)/100.0));
507 play_noteNumber = noteNumber;
508 play_velocity = velocity;
509 play_delay = delay;
510 play_releasetriggered = false;
511 lastVelocity[noteNumber] = velocity;
512 current_director.noteOn(tunedKey, velocity);
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 }
545 }
546
547 public void noteOff(int noteNumber, int velocity) {
548 noteNumber = restrict7Bit(noteNumber);
549 velocity = restrict7Bit(velocity);
550 noteOff_internal(noteNumber, velocity);
551
552 if (current_mixer != null)
553 current_mixer.noteOff(noteNumber, velocity);
554 }
555
556 private void noteOff_internal(int noteNumber, int velocity) {
557 synchronized (control_mutex) {
558
559 if (!mono) {
560 if (portamento) {
561 if (portamento_lastnote_ix != 127) {
562 portamento_lastnote[portamento_lastnote_ix] = noteNumber;
563 portamento_lastnote_ix++;
564 }
565 }
566 }
567
568 mainmixer.activity();
569 for (int i = 0; i < voices.length; i++) {
570 if (voices[i].on && voices[i].channel == channel
571 && voices[i].note == noteNumber
572 && voices[i].releaseTriggered == false) {
573 voices[i].noteOff(velocity);
574 }
575
576 if (voices[i].stealer_channel == this && voices[i].stealer_noteNumber == noteNumber) {
577 SoftVoice v = voices[i];
578 v.stealer_releaseTriggered = false;
579 v.stealer_channel = null;
580 v.stealer_performer = null;
581 v.stealer_voiceID = -1;
582 v.stealer_noteNumber = 0;
583 v.stealer_velocity = 0;
584 v.stealer_extendedConnectionBlocks = null;
585 v.stealer_channelmixer = null;
586 }
587 }
588
589
590
591 if (current_instrument == null) {
592 current_instrument
593 = synthesizer.findInstrument(program, bank, channel);
594 if (current_instrument == null)
595 return;
596 if (current_mixer != null)
597 mainmixer.stopMixer(current_mixer);
598 current_mixer = current_instrument.getSourceInstrument()
599 .getChannelMixer(this, synthesizer.getFormat());
600 if (current_mixer != null)
601 mainmixer.registerMixer(current_mixer);
602 current_director = current_instrument.getDirector(this, this);
603 applyInstrumentCustomization();
604
605 }
606 prevVoiceID = synthesizer.voiceIDCounter++;
607 firstVoice = true;
608 voiceNo = 0;
609
610 int tunedKey = (int)(Math.round(tuning.getTuning(noteNumber)/100.0));
611 play_noteNumber = noteNumber;
612 play_velocity = lastVelocity[noteNumber];
613 play_releasetriggered = true;
614 play_delay = 0;
615 current_director.noteOff(tunedKey, velocity);
616
617 }
618 }
619 private int[] lastVelocity = new int[128];
620 private int prevVoiceID;
621 private boolean firstVoice = true;
622 private int voiceNo = 0;
623 private int play_noteNumber = 0;
624 private int play_velocity = 0;
625 private int play_delay = 0;
626 private boolean play_releasetriggered = false;
627
628 public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks) {
629
630 int noteNumber = play_noteNumber;
631 int velocity = play_velocity;
632 int delay = play_delay;
633 boolean releasetriggered = play_releasetriggered;
634
635 SoftPerformer p = current_instrument.getPerformer(performerIndex);
636
637 if (firstVoice) {
638 firstVoice = false;
639 if (p.exclusiveClass != 0) {
640 int x = p.exclusiveClass;
641 for (int j = 0; j < voices.length; j++) {
642 if (voices[j].active && voices[j].channel == channel
643 && voices[j].exclusiveClass == x) {
644 if (!(p.selfNonExclusive && voices[j].note == noteNumber))
645 voices[j].shutdown();
646 }
647 }
648 }
649 }
650
651 voiceNo = findFreeVoice(voiceNo);
652
653 if (voiceNo == -1)
654 return;
655
656 initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity, delay,
657 connectionBlocks, current_mixer, releasetriggered);
658 }
659
660 public void noteOff(int noteNumber) {
661 if(noteNumber < 0 || noteNumber > 127) return;
662 noteOff_internal(noteNumber, 64);
663 }
664
665 public void setPolyPressure(int noteNumber, int pressure) {
666 noteNumber = restrict7Bit(noteNumber);
667 pressure = restrict7Bit(pressure);
668
669 if (current_mixer != null)
670 current_mixer.setPolyPressure(noteNumber, pressure);
671
672 synchronized (control_mutex) {
673 mainmixer.activity();
674 co_midi[noteNumber].get(0, "poly_pressure")[0] = pressure*(1.0/128.0);
675 polypressure[noteNumber] = pressure;
676 for (int i = 0; i < voices.length; i++) {
677 if (voices[i].active && voices[i].note == noteNumber)
678 voices[i].setPolyPressure(pressure);
679 }
680 }
681 }
682
683 public int getPolyPressure(int noteNumber) {
684 synchronized (control_mutex) {
685 return polypressure[noteNumber];
686 }
687 }
688
689 public void setChannelPressure(int pressure) {
690 pressure = restrict7Bit(pressure);
691 if (current_mixer != null)
692 current_mixer.setChannelPressure(pressure);
693 synchronized (control_mutex) {
694 mainmixer.activity();
695 co_midi_channel_pressure[0] = pressure * (1.0 / 128.0);
696 channelpressure = pressure;
697 for (int i = 0; i < voices.length; i++) {
698 if (voices[i].active)
699 voices[i].setChannelPressure(pressure);
700 }
701 }
702 }
703
704 public int getChannelPressure() {
705 synchronized (control_mutex) {
706 return channelpressure;
707 }
708 }
709
710 protected void applyInstrumentCustomization() {
711 if (cds_control_connections == null
712 && cds_channelpressure_connections == null
713 && cds_polypressure_connections == null) {
714 return;
715 }
716
717 ModelInstrument src_instrument = current_instrument.getSourceInstrument();
718 ModelPerformer[] performers = src_instrument.getPerformers();
719 ModelPerformer[] new_performers = new ModelPerformer[performers.length];
720 for (int i = 0; i < new_performers.length; i++) {
721 ModelPerformer performer = performers[i];
722 ModelPerformer new_performer = new ModelPerformer();
723 new_performer.setName(performer.getName());
724 new_performer.setExclusiveClass(performer.getExclusiveClass());
725 new_performer.setKeyFrom(performer.getKeyFrom());
726 new_performer.setKeyTo(performer.getKeyTo());
727 new_performer.setVelFrom(performer.getVelFrom());
728 new_performer.setVelTo(performer.getVelTo());
729 new_performer.getOscillators().addAll(performer.getOscillators());
730 new_performer.getConnectionBlocks().addAll(
731 performer.getConnectionBlocks());
732 new_performers[i] = new_performer;
733
734 List<ModelConnectionBlock> connblocks =
735 new_performer.getConnectionBlocks();
736
737 if (cds_control_connections != null) {
738 String cc = Integer.toString(cds_control_number);
739 Iterator<ModelConnectionBlock> iter = connblocks.iterator();
740 while (iter.hasNext()) {
741 ModelConnectionBlock conn = iter.next();
742 ModelSource[] sources = conn.getSources();
743 boolean removeok = false;
744 if (sources != null) {
745 for (int j = 0; j < sources.length; j++) {
746 ModelSource src = sources[j];
747 if ("midi_cc".equals(src.getIdentifier().getObject())
748 && cc.equals(src.getIdentifier().getVariable())) {
749 removeok = true;
750 }
751 }
752 }
753 if (removeok)
754 iter.remove();
755 }
756 for (int j = 0; j < cds_control_connections.length; j++)
757 connblocks.add(cds_control_connections[j]);
758 }
759
760 if (cds_polypressure_connections != null) {
761 Iterator<ModelConnectionBlock> iter = connblocks.iterator();
762 while (iter.hasNext()) {
763 ModelConnectionBlock conn = iter.next();
764 ModelSource[] sources = conn.getSources();
765 boolean removeok = false;
766 if (sources != null) {
767 for (int j = 0; j < sources.length; j++) {
768 ModelSource src = sources[j];
769 if ("midi".equals(src.getIdentifier().getObject())
770 && "poly_pressure".equals(
771 src.getIdentifier().getVariable())) {
772 removeok = true;
773 }
774 }
775 }
776 if (removeok)
777 iter.remove();
778 }
779 for (int j = 0; j < cds_polypressure_connections.length; j++)
780 connblocks.add(cds_polypressure_connections[j]);
781 }
782
783
784 if (cds_channelpressure_connections != null) {
785 Iterator<ModelConnectionBlock> iter = connblocks.iterator();
786 while (iter.hasNext()) {
787 ModelConnectionBlock conn = iter.next();
788 ModelSource[] sources = conn.getSources();
789 boolean removeok = false;
790 if (sources != null) {
791 for (int j = 0; j < sources.length; j++) {
792 ModelIdentifier srcid = sources[j].getIdentifier();
793 if ("midi".equals(srcid.getObject()) &&
794 "channel_pressure".equals(srcid.getVariable())) {
795 removeok = true;
796 }
797 }
798 }
799 if (removeok)
800 iter.remove();
801 }
802 for (int j = 0; j < cds_channelpressure_connections.length; j++)
803 connblocks.add(cds_channelpressure_connections[j]);
804 }
805
806 }
807
808 current_instrument = new SoftInstrument(src_instrument, new_performers);
809
810 }
811
812 private ModelConnectionBlock[] createModelConnections(ModelIdentifier sid,
813 int[] destination, int[] range) {
814
815
816
817
818
819
820
821
822
823
824
825
826 List<ModelConnectionBlock> conns = new ArrayList<ModelConnectionBlock>();
827
828 for (int i = 0; i < destination.length; i++) {
829 int d = destination[i];
830 int r = range[i];
831 if (d == 0) {
832 double scale = (r - 64) * 100;
833 ModelConnectionBlock conn = new ModelConnectionBlock(
834 new ModelSource(sid,
835 ModelStandardTransform.DIRECTION_MIN2MAX,
836 ModelStandardTransform.POLARITY_UNIPOLAR,
837 ModelStandardTransform.TRANSFORM_LINEAR),
838 scale,
839 new ModelDestination(
840 new ModelIdentifier("osc", "pitch")));
841 conns.add(conn);
842
843 }
844 if (d == 1) {
845 double scale = (r / 64.0 - 1.0) * 9600.0;
846 ModelConnectionBlock conn;
847 if (scale > 0) {
848 conn = new ModelConnectionBlock(
849 new ModelSource(sid,
850 ModelStandardTransform.DIRECTION_MAX2MIN,
851 ModelStandardTransform.POLARITY_UNIPOLAR,
852 ModelStandardTransform.TRANSFORM_LINEAR),
853 -scale,
854 new ModelDestination(
855 ModelDestination.DESTINATION_FILTER_FREQ));
856 } else {
857 conn = new ModelConnectionBlock(
858 new ModelSource(sid,
859 ModelStandardTransform.DIRECTION_MIN2MAX,
860 ModelStandardTransform.POLARITY_UNIPOLAR,
861 ModelStandardTransform.TRANSFORM_LINEAR),
862 scale,
863 new ModelDestination(
864 ModelDestination.DESTINATION_FILTER_FREQ));
865 }
866 conns.add(conn);
867 }
868 if (d == 2) {
869 final double scale = (r / 64.0);
870 ModelTransform mt = new ModelTransform() {
871 double s = scale;
872 public double transform(double value) {
873 if (s < 1)
874 value = s + (value * (1.0 - s));
875 else if (s > 1)
876 value = 1 + (value * (s - 1.0));
877 else
878 return 0;
879 return -((5.0 / 12.0) / Math.log(10)) * Math.log(value);
880 }
881 };
882
883 ModelConnectionBlock conn = new ModelConnectionBlock(
884 new ModelSource(sid, mt), -960,
885 new ModelDestination(ModelDestination.DESTINATION_GAIN));
886 conns.add(conn);
887
888 }
889 if (d == 3) {
890 double scale = (r / 64.0 - 1.0) * 9600.0;
891 ModelConnectionBlock conn = new ModelConnectionBlock(
892 new ModelSource(ModelSource.SOURCE_LFO1,
893 ModelStandardTransform.DIRECTION_MIN2MAX,
894 ModelStandardTransform.POLARITY_BIPOLAR,
895 ModelStandardTransform.TRANSFORM_LINEAR),
896 new ModelSource(sid,
897 ModelStandardTransform.DIRECTION_MIN2MAX,
898 ModelStandardTransform.POLARITY_UNIPOLAR,
899 ModelStandardTransform.TRANSFORM_LINEAR),
900 scale,
901 new ModelDestination(
902 ModelDestination.DESTINATION_PITCH));
903 conns.add(conn);
904 }
905 if (d == 4) {
906 double scale = (r / 128.0) * 2400.0;
907 ModelConnectionBlock conn = new ModelConnectionBlock(
908 new ModelSource(ModelSource.SOURCE_LFO1,
909 ModelStandardTransform.DIRECTION_MIN2MAX,
910 ModelStandardTransform.POLARITY_BIPOLAR,
911 ModelStandardTransform.TRANSFORM_LINEAR),
912 new ModelSource(sid,
913 ModelStandardTransform.DIRECTION_MIN2MAX,
914 ModelStandardTransform.POLARITY_UNIPOLAR,
915 ModelStandardTransform.TRANSFORM_LINEAR),
916 scale,
917 new ModelDestination(
918 ModelDestination.DESTINATION_FILTER_FREQ));
919 conns.add(conn);
920 }
921 if (d == 5) {
922 final double scale = (r / 127.0);
923
924 ModelTransform mt = new ModelTransform() {
925 double s = scale;
926 public double transform(double value) {
927 return -((5.0 / 12.0) / Math.log(10))
928 * Math.log(1 - value * s);
929 }
930 };
931
932 ModelConnectionBlock conn = new ModelConnectionBlock(
933 new ModelSource(ModelSource.SOURCE_LFO1,
934 ModelStandardTransform.DIRECTION_MIN2MAX,
935 ModelStandardTransform.POLARITY_UNIPOLAR,
936 ModelStandardTransform.TRANSFORM_LINEAR),
937 new ModelSource(sid, mt),
938 -960,
939 new ModelDestination(
940 ModelDestination.DESTINATION_GAIN));
941 conns.add(conn);
942 }
943 }
944
945 return conns.toArray(new ModelConnectionBlock[conns.size()]);
946 }
947
948 public void mapPolyPressureToDestination(int[] destination, int[] range) {
949 current_instrument = null;
950 if (destination.length == 0) {
951 cds_polypressure_connections = null;
952 return;
953 }
954 cds_polypressure_connections
955 = createModelConnections(
956 new ModelIdentifier("midi", "poly_pressure"),
957 destination, range);
958 }
959
960 public void mapChannelPressureToDestination(int[] destination, int[] range) {
961 current_instrument = null;
962 if (destination.length == 0) {
963 cds_channelpressure_connections = null;
964 return;
965 }
966 cds_channelpressure_connections
967 = createModelConnections(
968 new ModelIdentifier("midi", "channel_pressure"),
969 destination, range);
970 }
971
972 public void mapControlToDestination(int control, int[] destination, int[] range) {
973
974 if (!((control >= 0x01 && control <= 0x1F)
975 || (control >= 0x40 && control <= 0x5F))) {
976 cds_control_connections = null;
977 return;
978 }
979
980 current_instrument = null;
981 cds_control_number = control;
982 if (destination.length == 0) {
983 cds_control_connections = null;
984 return;
985 }
986 cds_control_connections
987 = createModelConnections(
988 new ModelIdentifier("midi_cc", Integer.toString(control)),
989 destination, range);
990 }
991
992 public void controlChangePerNote(int noteNumber, int controller, int value) {
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014 if (keybasedcontroller_active == null) {
1015 keybasedcontroller_active = new boolean[128][];
1016 keybasedcontroller_value = new double[128][];
1017 }
1018 if (keybasedcontroller_active[noteNumber] == null) {
1019 keybasedcontroller_active[noteNumber] = new boolean[128];
1020 Arrays.fill(keybasedcontroller_active[noteNumber], false);
1021 keybasedcontroller_value[noteNumber] = new double[128];
1022 Arrays.fill(keybasedcontroller_value[noteNumber], 0);
1023 }
1024
1025 if (value == -1) {
1026 keybasedcontroller_active[noteNumber][controller] = false;
1027 } else {
1028 keybasedcontroller_active[noteNumber][controller] = true;
1029 keybasedcontroller_value[noteNumber][controller] = value / 128.0;
1030 }
1031
1032 if (controller < 120) {
1033 for (int i = 0; i < voices.length; i++)
1034 if (voices[i].active)
1035 voices[i].controlChange(controller, -1);
1036 } else if (controller == 120) {
1037 for (int i = 0; i < voices.length; i++)
1038 if (voices[i].active)
1039 voices[i].rpnChange(1, -1);
1040 } else if (controller == 121) {
1041 for (int i = 0; i < voices.length; i++)
1042 if (voices[i].active)
1043 voices[i].rpnChange(2, -1);
1044 }
1045
1046 }
1047
1048 public int getControlPerNote(int noteNumber, int controller) {
1049 if (keybasedcontroller_active == null)
1050 return -1;
1051 if (keybasedcontroller_active[noteNumber] == null)
1052 return -1;
1053 if (!keybasedcontroller_active[noteNumber][controller])
1054 return -1;
1055 return (int)(keybasedcontroller_value[noteNumber][controller] * 128);
1056 }
1057
1058 public void controlChange(int controller, int value) {
1059 controller = restrict7Bit(controller);
1060 value = restrict7Bit(value);
1061 if (current_mixer != null)
1062 current_mixer.controlChange(controller, value);
1063
1064 synchronized (control_mutex) {
1065 switch (controller) {
1066
1067
1068
1069
1070
1071
1072
1073 case 5:
1074
1075
1076 double x = -Math.asin((value / 128.0) * 2 - 1) / Math.PI + 0.5;
1077 x = Math.pow(100000.0, x) / 100.0;
1078
1079 x = x / 100.0;
1080 x = x * 1000.0;
1081 x = x / synthesizer.getControlRate();
1082 portamento_time = x;
1083 break;
1084 case 6:
1085 case 38:
1086 case 96:
1087 case 97:
1088 int val = 0;
1089 if (nrpn_control != RPN_NULL_VALUE) {
1090 int[] val_i = co_midi_nrpn_nrpn_i.get(nrpn_control);
1091 if (val_i != null)
1092 val = val_i[0];
1093 }
1094 if (rpn_control != RPN_NULL_VALUE) {
1095 int[] val_i = co_midi_rpn_rpn_i.get(rpn_control);
1096 if (val_i != null)
1097 val = val_i[0];
1098 }
1099
1100 if (controller == 6)
1101 val = (val & 127) + (value << 7);
1102 else if (controller == 38)
1103 val = (val & (127 << 7)) + value;
1104 else if (controller == 96 || controller == 97) {
1105 int step = 1;
1106 if (rpn_control == 2 || rpn_control == 3 || rpn_control == 4)
1107 step = 128;
1108 if (controller == 96)
1109 val += step;
1110 if (controller == 97)
1111 val -= step;
1112 }
1113
1114 if (nrpn_control != RPN_NULL_VALUE)
1115 nrpnChange(nrpn_control, val);
1116 if (rpn_control != RPN_NULL_VALUE)
1117 rpnChange(rpn_control, val);
1118
1119 break;
1120 case 64:
1121 boolean on = value >= 64;
1122 if (sustain != on) {
1123 sustain = on;
1124 if (!on) {
1125 for (int i = 0; i < voices.length; i++) {
1126 if (voices[i].active && voices[i].sustain &&
1127 voices[i].channel == channel) {
1128 voices[i].sustain = false;
1129 if (!voices[i].on) {
1130 voices[i].on = true;
1131 voices[i].noteOff(0);
1132 }
1133 }
1134 }
1135 } else {
1136 for (int i = 0; i < voices.length; i++)
1137 if (voices[i].active && voices[i].channel == channel)
1138 voices[i].redamp();
1139 }
1140 }
1141 break;
1142 case 65:
1143
1144 portamento = value >= 64;
1145 portamento_lastnote[0] = -1;
1146
1147
1148
1149
1150 portamento_lastnote_ix = 0;
1151 break;
1152 case 66:
1153 on = value >= 64;
1154 if (on) {
1155 for (int i = 0; i < voices.length; i++) {
1156 if (voices[i].active && voices[i].on &&
1157 voices[i].channel == channel) {
1158 voices[i].sostenuto = true;
1159 }
1160 }
1161 }
1162 if (!on) {
1163 for (int i = 0; i < voices.length; i++) {
1164 if (voices[i].active && voices[i].sostenuto &&
1165 voices[i].channel == channel) {
1166 voices[i].sostenuto = false;
1167 if (!voices[i].on) {
1168 voices[i].on = true;
1169 voices[i].noteOff(0);
1170 }
1171 }
1172 }
1173 }
1174 break;
1175 case 98:
1176 nrpn_control = (nrpn_control & (127 << 7)) + value;
1177 rpn_control = RPN_NULL_VALUE;
1178 break;
1179 case 99:
1180 nrpn_control = (nrpn_control & 127) + (value << 7);
1181 rpn_control = RPN_NULL_VALUE;
1182 break;
1183 case 100:
1184 rpn_control = (rpn_control & (127 << 7)) + value;
1185 nrpn_control = RPN_NULL_VALUE;
1186 break;
1187 case 101:
1188 rpn_control = (rpn_control & 127) + (value << 7);
1189 nrpn_control = RPN_NULL_VALUE;
1190 break;
1191 case 120:
1192 allSoundOff();
1193 break;
1194 case 121:
1195 resetAllControllers(value == 127);
1196 break;
1197 case 122:
1198 localControl(value >= 64);
1199 break;
1200 case 123:
1201 allNotesOff();
1202 break;
1203 case 124:
1204 setOmni(false);
1205 break;
1206 case 125:
1207 setOmni(true);
1208 break;
1209 case 126:
1210 if (value == 1)
1211 setMono(true);
1212 break;
1213 case 127:
1214 setMono(false);
1215 break;
1216
1217 default:
1218 break;
1219 }
1220
1221 co_midi_cc_cc[controller][0] = value * (1.0 / 128.0);
1222
1223 if (controller == 0x00) {
1224 bank = (value << 7);
1225 return;
1226 }
1227
1228 if (controller == 0x20) {
1229 bank = (bank & (127 << 7)) + value;
1230 return;
1231 }
1232
1233 this.controller[controller] = value;
1234 if(controller < 0x20)
1235 this.controller[controller + 0x20] = 0;
1236
1237 for (int i = 0; i < voices.length; i++)
1238 if (voices[i].active)
1239 voices[i].controlChange(controller, value);
1240
1241 }
1242 }
1243
1244 public int getController(int controller) {
1245 synchronized (control_mutex) {
1246
1247
1248 return this.controller[controller] & 127;
1249 }
1250 }
1251
1252 public void tuningChange(int program) {
1253 tuningChange(0, program);
1254 }
1255
1256 public void tuningChange(int bank, int program) {
1257 synchronized (control_mutex) {
1258 tuning = synthesizer.getTuning(new Patch(bank, program));
1259 }
1260 }
1261
1262 public void programChange(int program) {
1263 programChange(bank, program);
1264 }
1265
1266 public void programChange(int bank, int program) {
1267 bank = restrict14Bit(bank);
1268 program = restrict7Bit(program);
1269 synchronized (control_mutex) {
1270 mainmixer.activity();
1271 if(this.bank != bank || this.program != program)
1272 {
1273 this.bank = bank;
1274 this.program = program;
1275 current_instrument = null;
1276 }
1277 }
1278 }
1279
1280 public int getProgram() {
1281 synchronized (control_mutex) {
1282 return program;
1283 }
1284 }
1285
1286 public void setPitchBend(int bend) {
1287 bend = restrict14Bit(bend);
1288 if (current_mixer != null)
1289 current_mixer.setPitchBend(bend);
1290 synchronized (control_mutex) {
1291 mainmixer.activity();
1292 co_midi_pitch[0] = bend * (1.0 / 16384.0);
1293 pitchbend = bend;
1294 for (int i = 0; i < voices.length; i++)
1295 if (voices[i].active)
1296 voices[i].setPitchBend(bend);
1297 }
1298 }
1299
1300 public int getPitchBend() {
1301 synchronized (control_mutex) {
1302 return pitchbend;
1303 }
1304 }
1305
1306 public void nrpnChange(int controller, int value) {
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316 if (synthesizer.getGeneralMidiMode() == 0) {
1317 if (controller == (0x01 << 7) + (0x08))
1318 controlChange(76, value >> 7);
1319 if (controller == (0x01 << 7) + (0x09))
1320 controlChange(77, value >> 7);
1321 if (controller == (0x01 << 7) + (0x0A))
1322 controlChange(78, value >> 7);
1323 if (controller == (0x01 << 7) + (0x20))
1324 controlChange(74, value >> 7);
1325 if (controller == (0x01 << 7) + (0x21))
1326 controlChange(71, value >> 7);
1327 if (controller == (0x01 << 7) + (0x63))
1328 controlChange(73, value >> 7);
1329 if (controller == (0x01 << 7) + (0x64))
1330 controlChange(75, value >> 7);
1331 if (controller == (0x01 << 7) + (0x66))
1332 controlChange(72, value >> 7);
1333
1334 if (controller >> 7 == 0x18)
1335 controlChangePerNote(controller % 128, 120, value >> 7);
1336 if (controller >> 7 == 0x1A)
1337 controlChangePerNote(controller % 128, 7, value >> 7);
1338 if (controller >> 7 == 0x1C)
1339 controlChangePerNote(controller % 128, 10, value >> 7);
1340 if (controller >> 7 == 0x1D)
1341 controlChangePerNote(controller % 128, 91, value >> 7);
1342 if (controller >> 7 == 0x1E)
1343 controlChangePerNote(controller % 128, 93, value >> 7);
1344 }
1345
1346 int[] val_i = co_midi_nrpn_nrpn_i.get(controller);
1347 double[] val_d = co_midi_nrpn_nrpn.get(controller);
1348 if (val_i == null) {
1349 val_i = new int[1];
1350 co_midi_nrpn_nrpn_i.put(controller, val_i);
1351 }
1352 if (val_d == null) {
1353 val_d = new double[1];
1354 co_midi_nrpn_nrpn.put(controller, val_d);
1355 }
1356 val_i[0] = value;
1357 val_d[0] = val_i[0] * (1.0 / 16384.0);
1358
1359 for (int i = 0; i < voices.length; i++)
1360 if (voices[i].active)
1361 voices[i].nrpnChange(controller, val_i[0]);
1362
1363 }
1364
1365 public void rpnChange(int controller, int value) {
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375 if (controller == 3) {
1376 tuning_program = (value >> 7) & 127;
1377 tuningChange(tuning_bank, tuning_program);
1378 }
1379 if (controller == 4) {
1380 tuning_bank = (value >> 7) & 127;
1381 }
1382
1383 int[] val_i = co_midi_rpn_rpn_i.get(controller);
1384 double[] val_d = co_midi_rpn_rpn.get(controller);
1385 if (val_i == null) {
1386 val_i = new int[1];
1387 co_midi_rpn_rpn_i.put(controller, val_i);
1388 }
1389 if (val_d == null) {
1390 val_d = new double[1];
1391 co_midi_rpn_rpn.put(controller, val_d);
1392 }
1393 val_i[0] = value;
1394 val_d[0] = val_i[0] * (1.0 / 16384.0);
1395
1396 for (int i = 0; i < voices.length; i++)
1397 if (voices[i].active)
1398 voices[i].rpnChange(controller, val_i[0]);
1399 }
1400
1401 public void resetAllControllers() {
1402 resetAllControllers(false);
1403 }
1404
1405 public void resetAllControllers(boolean allControls) {
1406 synchronized (control_mutex) {
1407 mainmixer.activity();
1408
1409 for (int i = 0; i < 128; i++) {
1410 setPolyPressure(i, 0);
1411 }
1412 setChannelPressure(0);
1413 setPitchBend(8192);
1414 for (int i = 0; i < 128; i++) {
1415 if (!dontResetControls[i])
1416 controlChange(i, 0);
1417 }
1418
1419 controlChange(71, 64);
1420 controlChange(72, 64);
1421 controlChange(73, 64);
1422 controlChange(74, 64);
1423 controlChange(75, 64);
1424 controlChange(76, 64);
1425 controlChange(77, 64);
1426 controlChange(78, 64);
1427
1428 controlChange(8, 64);
1429 controlChange(11, 127);
1430 controlChange(98, 127);
1431 controlChange(99, 127);
1432 controlChange(100, 127);
1433 controlChange(101, 127);
1434
1435
1436 if (allControls) {
1437
1438 keybasedcontroller_active = null;
1439 keybasedcontroller_value = null;
1440
1441 controlChange(7, 100);
1442 controlChange(10, 64);
1443 controlChange(91, 40);
1444
1445 for (int controller : co_midi_rpn_rpn.keySet()) {
1446
1447 if (controller != 3 && controller != 4)
1448 rpnChange(controller, 0);
1449 }
1450 for (int controller : co_midi_nrpn_nrpn.keySet())
1451 nrpnChange(controller, 0);
1452 rpnChange(0, 2 << 7);
1453 rpnChange(1, 64 << 7);
1454 rpnChange(2, 64 << 7);
1455 rpnChange(5, 64);
1456
1457 tuning_bank = 0;
1458 tuning_program = 0;
1459 tuning = new SoftTuning();
1460
1461 }
1462
1463 }
1464 }
1465
1466 public void allNotesOff() {
1467 if (current_mixer != null)
1468 current_mixer.allNotesOff();
1469 synchronized (control_mutex) {
1470 for (int i = 0; i < voices.length; i++)
1471 if (voices[i].on && voices[i].channel == channel
1472 && voices[i].releaseTriggered == false) {
1473 voices[i].noteOff(0);
1474 }
1475 }
1476 }
1477
1478 public void allSoundOff() {
1479 if (current_mixer != null)
1480 current_mixer.allSoundOff();
1481 synchronized (control_mutex) {
1482 for (int i = 0; i < voices.length; i++)
1483 if (voices[i].on && voices[i].channel == channel)
1484 voices[i].soundOff();
1485 }
1486 }
1487
1488 public boolean localControl(boolean on) {
1489 return false;
1490 }
1491
1492 public void setMono(boolean on) {
1493 if (current_mixer != null)
1494 current_mixer.setMono(on);
1495 synchronized (control_mutex) {
1496 allNotesOff();
1497 mono = on;
1498 }
1499 }
1500
1501 public boolean getMono() {
1502 synchronized (control_mutex) {
1503 return mono;
1504 }
1505 }
1506
1507 public void setOmni(boolean on) {
1508 if (current_mixer != null)
1509 current_mixer.setOmni(on);
1510 allNotesOff();
1511
1512 }
1513
1514 public boolean getOmni() {
1515 return false;
1516 }
1517
1518 public void setMute(boolean mute) {
1519 if (current_mixer != null)
1520 current_mixer.setMute(mute);
1521 synchronized (control_mutex) {
1522 this.mute = mute;
1523 for (int i = 0; i < voices.length; i++)
1524 if (voices[i].active && voices[i].channel == channel)
1525 voices[i].setMute(mute);
1526 }
1527 }
1528
1529 public boolean getMute() {
1530 synchronized (control_mutex) {
1531 return mute;
1532 }
1533 }
1534
1535 public void setSolo(boolean soloState) {
1536 if (current_mixer != null)
1537 current_mixer.setSolo(soloState);
1538
1539 synchronized (control_mutex) {
1540 this.solo = soloState;
1541
1542 boolean soloinuse = false;
1543 for (SoftChannel c : synthesizer.channels) {
1544 if (c.solo) {
1545 soloinuse = true;
1546 break;
1547 }
1548 }
1549
1550 if (!soloinuse) {
1551 for (SoftChannel c : synthesizer.channels)
1552 c.setSoloMute(false);
1553 return;
1554 }
1555
1556 for (SoftChannel c : synthesizer.channels)
1557 c.setSoloMute(!c.solo);
1558
1559 }
1560
1561 }
1562
1563 private void setSoloMute(boolean mute) {
1564 synchronized (control_mutex) {
1565 if (solomute == mute)
1566 return;
1567 this.solomute = mute;
1568 for (int i = 0; i < voices.length; i++)
1569 if (voices[i].active && voices[i].channel == channel)
1570 voices[i].setSoloMute(solomute);
1571 }
1572 }
1573
1574 public boolean getSolo() {
1575 synchronized (control_mutex) {
1576 return solo;
1577 }
1578 }
1579 }